package com.slofzx.nuoda.evaluation.project.compont.exported;

import com.alibaba.fastjson.JSON;
import com.slofzx.nuoda.common.dto.CompanyDTO;
import com.slofzx.nuoda.common.dto.DictDTO;
import com.slofzx.nuoda.common.dto.DictValueDTO;
import com.slofzx.nuoda.common.exception.ServiceException;
import com.slofzx.nuoda.common.util.DataConvertUtil;
import com.slofzx.nuoda.common.vo.AjaxResultVO;
import com.slofzx.nuoda.common.vo.CompanyVO;
import com.slofzx.nuoda.common.vo.DictVO;
import com.slofzx.nuoda.common.vo.DictValueVO;
import com.slofzx.nuoda.evaluation.feign.ComputeInvokeClient;
import com.slofzx.nuoda.evaluation.project.builder.BatchExportExcelBuilder;
import com.slofzx.nuoda.evaluation.project.builder.MergeExportExcelBuilder;
import com.slofzx.nuoda.evaluation.project.builder.ResultExportExcelBuilder;
import com.slofzx.nuoda.evaluation.project.compont.AbstractExcelComponent;
import com.slofzx.nuoda.evaluation.project.compont.CopyExcelComponent;
import com.slofzx.nuoda.evaluation.project.dto.*;
import com.slofzx.nuoda.evaluation.project.enums.*;
import com.slofzx.nuoda.evaluation.project.service.ExportTemplateDetailService;
import com.slofzx.nuoda.evaluation.project.service.ProjectReportDetailYearService;
import com.slofzx.nuoda.evaluation.project.util.BusiUtil;
import com.slofzx.nuoda.evaluation.project.util.SpireExcelUtil;
import com.slofzx.nuoda.evaluation.project.vo.*;
import com.slofzx.nuoda.evaluation.steretype.ExcelExportItem;
import com.slofzx.nuoda.excel.vo.ExcelPreviewDataVO;
import com.slofzx.nuoda.excel.vo.SheetConfigVO;
import com.spire.xls.*;
import com.spire.xls.Workbook;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
public abstract class AbstractExportExcelComponent extends AbstractExcelComponent {
    private static final Logger logger = LoggerFactory.getLogger(AbstractExportExcelComponent.class);
    protected static List<CompanyVO> COMPANY_LIST = new ArrayList<>();
    protected static Map<String, String> COMPANY_NAME_MAP = new HashMap<>();

    @Autowired
    private ComputeInvokeClient computeInvokeClient;
    @Autowired
    private ExportTemplateDetailService exportTemplateDetailService;
    @Autowired
    private ProjectReportDetailYearService projectReportDetailYearService;
    private CopyExcelComponent copyExcelComponent;
    @Value("${nuoda.office.root:21810}")
    private String officeRootId;
    //*********************************普通导出******************************************//
    /**
     * 普通导出
     * @param context
     * @return
     */
    public byte[] exportExcel(ExportExcelContext context) {
        // 获取录入参数文档
        final StopWatch stopWatch = new StopWatch();

        stopWatch.start("param");
        final Workbook workbook = getParamExportWorkbook(context);
        stopWatch.stop();
        // 生成自定义模板数据
        stopWatch.start("version");
        org.apache.poi.ss.usermodel.Workbook customResultWorkbook = exportComputeVersionData(context);
        stopWatch.stop();
        stopWatch.start("copy");
        // 从自定义文档将数据拷贝到导出文档
        final org.apache.poi.ss.usermodel.Workbook workbookApache = copySheet(context,workbook, customResultWorkbook);
        stopWatch.stop();
        // 将文件转换为数组
        stopWatch.start("11");
        final byte[] bytes = convert2Bytes(context, workbookApache);
        stopWatch.stop();
        logger.info(stopWatch.getTotalTimeSeconds()+"");
        logger.info(stopWatch.prettyPrint());
        return bytes;

    }

    /**
     * 获取录入参数文档
     * @param context
     * @return
     */
    private Workbook getParamExportWorkbook(ExportExcelContext context) {
        final ExcelPreviewDataVO excelPreviewData = getExcelPreviewData(getTemplatePath(context.getProductType()),true);
        // 这一行必须在读取模板文件的下一行
        final Workbook workbook = SpireExcelUtil.getWorkbook(byteArrayOutputStream);
        try {
            byteArrayOutputStream.close();
        } catch (IOException e) {
            logger.error("导出文件拷贝失败");
        }
        if (workbook == null) {
            logger.error("加载导出文件失败 batchId={}", context.getId());
            throw new ServiceException("加载导出文件失败", "加载导出文件失败", null);
        }
        context.setWorkbook(workbook);
        for (int i = 0; i < excelPreviewData.getSheetList().size(); i++) {
            context.setSheetIndex(i);
            final SheetConfigVO sheetConfigVO = (SheetConfigVO) excelPreviewData.getSheetList().get(i);
            final Map<String, String> fieldPositionMap = getFieldPositionMap(sheetConfigVO);
            context.setFieldPositionMap(fieldPositionMap);
            if (i == 0) {
                exportCostEvaMethod(context);
                exportBatchCommonParam(context);
            } else if (i == 1) {
                exportProjectData(context);
            }
        }
        return workbook;
    }


    /**
     * 导出任务成本计算方法
     *
     * @param  context 导出excel 上下文
     *
     */
    private void exportCostEvaMethod(ExportExcelContext context) {
        // String costEvaMethod, Map<String, String> fieldPositionMap, Workbook workbook, int sheetIndex
        Map<String, String> fieldPositionMap = context.getFieldPositionMap();
        Workbook workbook = context.getWorkbook();
        final String enumName = getEnumName(context.getCostEvaMethod(), CostEvaMethodEnum.class);
        final String position = fieldPositionMap.get("costEvaMethod");
        String[] split = position.split(BusiUtil.DELIMITER);
        String rowStr = split[0];
        String colStr = split[1];
        final Integer rowIndex = Integer.parseInt(rowStr)+1;
        String[] data = new String[1];
        data[0] = enumName;
        String colIndexStr =  colStr.replace(COL_STR, StringUtils.EMPTY);
        final Integer colIndex = Integer.parseInt(colIndexStr)+1;
        final Worksheet worksheet = workbook.getWorksheets().get(context.getSheetIndex());
        SpireExcelUtil.saveExcelRowData(worksheet, data, rowIndex, colIndex);
    }

    /**
     * 导出评价结果
     *
     */
    private org.apache.poi.ss.usermodel.Workbook exportComputeVersionData(ExportExcelContext context) {
        if (context.isEmptyProject()) {
            return new XSSFWorkbook();
        }
        // final Workbook workbook = context.getWorkbook();
        final ProjectInfoDTO projectInfoDTO = context.getProjectInfoDTO();
        //final Worksheet worksheet = workbook.getWorksheets().get(context.getSheetIndex());
        projectInfoDTO.setBatchId(context.getId());
        final List<ProjectInfoVO> projectInfoVOS = projectInfoService.queryVOList(projectInfoDTO);
        final Set<String> computeVersionIdList = projectInfoVOS.stream().map(ProjectInfoVO::getComputeId).collect(Collectors.toSet());
        final Map<String, List<ProjectReportDetailYearVO>> detailYearMap = getProjectReportDetailListMap(computeVersionIdList);

        int maxYear = 0;
        List<Map<String,Object>> projectMapList = new ArrayList<>(projectInfoVOS.size());
        final Map<String, List<ExcelExportItem>> excelExportItemGroupMap = getExcelExportItemGroupMap(context.getExcelExportItemList());
        for (ProjectInfoVO projectInfoVO : projectInfoVOS) {
            if (Objects.isNull(projectInfoVO)) {
                continue;
            }
            final Map<String, Object> map = BusiUtil.parseObject2Map(projectInfoVO, excelExportItemGroupMap);
            for (String key : map.keySet()) {
                final Object value = convertProjectData(context.getProductType(), key, map.get(key));
                map.put(key,value);
            }
            map.put("id",projectInfoVO.getId());
            projectMapList.add(map);
            maxYear = projectInfoVO.getEvaluationPeriod() > maxYear ? projectInfoVO.getEvaluationPeriod():maxYear;
        }
        List<BatchCommonDataVO> batchCommonDataVOList = getBatchCommonDataVOS(context.getId());
        // 生成年列表
        List<Integer> yearList = new ArrayList<>(maxYear);
        for (int i = 0; i <maxYear; i++) {
            yearList.add(i+1);
        }
        // yearList.add(maxYear);
        final ResultExportExcelBuilder resultExcelBuilder = new ResultExportExcelBuilder(context.getConfig(), excelExportItemGroupMap);
        return resultExcelBuilder
                .projectMapList(projectMapList)
                .batchCommonDataVOList(batchCommonDataVOList)
                .projectReportDetailYearVOMap(detailYearMap)
                .yearList(yearList)
                .build();

    }






    private void saveEmptyData(Map<String, String> fieldPositionMap, Integer rowIndex, Worksheet worksheet) {
        String[] rowData = new String[1000];
        for (Map.Entry<String, String> entry : fieldPositionMap.entrySet()) {
            final Integer colIndex = getColIndex(entry.getValue());
            rowData[colIndex] = StringUtils.EMPTY;
        }
        rowData[0] = StringUtils.EMPTY;
        SpireExcelUtil.saveExcelRowData(worksheet, rowData, rowIndex);
    }

    /**
     * 导出项目数据及年份数据
     *
     * @param context
     */
    private void exportProjectData(ExportExcelContext context) {
        // String targetId,ProductTypeEnum productType, ProjectInfoDTO projectInfoDTO, Workbook workbook, int sheetIndex, Integer rowIndex;
        Map<String, String> fieldPositionMap = context.getFieldPositionMap();
        final ProjectInfoDTO projectInfoDTO = context.getProjectInfoDTO();
        final Workbook workbook = context.getWorkbook();
        Integer rowIndex =getRowIndex(fieldPositionMap,"index");
        final Worksheet worksheet = workbook.getWorksheets().get(context.getSheetIndex());
        projectInfoDTO.setBatchId(context.getId());
        final List<ProjectInfoVO> projectInfoVOS = projectInfoService.queryVOList(projectInfoDTO);
        if (CollectionUtils.isEmpty(projectInfoVOS)) {
            context.setEmptyProject(true);
            saveEmptyData(fieldPositionMap, rowIndex, worksheet);
            return;
        }
        // 不能删除获取组织机构
        getCompanyList();
        final Set<String> projectInfoSet = projectInfoVOS.stream().map(ProjectInfoVO::getId).collect(Collectors.toSet());
        final Map<String, List<ProjectYearDataVO>> yearDataMap = getProjectYearDataMap(context.getId(), projectInfoSet);

        for (int i = 0; i < projectInfoVOS.size(); i++) {
            String[] rowData = new String[1000];

            //List<String> rowData = new ArrayList<>();
            final ProjectInfoVO infoVO = projectInfoVOS.get(i);
            final Map<String, Object> map = JSON.parseObject(JSON.toJSONString(infoVO), Map.class);
            for (Map.Entry<String, String> entry : fieldPositionMap.entrySet()) {
                final Integer colIndex = getColIndex(entry.getValue());
                final String filed = entry.getKey();
                Map<Integer, Map<String, String>> yearMap = new HashMap<>();
                if (MapUtils.isNotEmpty(yearDataMap)) {
                    List<ProjectYearDataVO> yearDataVOList = yearDataMap.get(infoVO.getId());
                    if (CollectionUtils.isNotEmpty(yearDataVOList)) {
                        Map<Integer, ProjectYearDataVO> yearDataVOMap = yearDataVOList.stream().collect(Collectors.toMap(ProjectYearDataVO::getYear, Function.identity(), (v1, v2) -> v1));
                        for (Map.Entry<Integer, ProjectYearDataVO> yearDataVOEntry : yearDataVOMap.entrySet()) {
                            final Map<String, String> targetMap = JSON.parseObject(JSON.toJSONString(yearDataVOEntry.getValue()), Map.class);
                            yearMap.put(yearDataVOEntry.getKey(), targetMap);
                        }
                    }
                }
                // 获取年份枚举
                final ImportExcelYearDataConfigEnum dataConfigEnum = BusiUtil.getEnumById(filed, ImportExcelYearDataConfigEnum.class);
                if (dataConfigEnum != null) {
                    // 如果是年份枚举则按照配置继续往后填充
                    for (int year = 0; year <= dataConfigEnum.getYear(); year++) {
                        Map<String, String> yearData = null;
                        if (dataConfigEnum.isTotal()) {
                            yearData = yearMap.get(year);
                        } else {
                            if (year == dataConfigEnum.getYear()) {
                                continue;
                            }
                            yearData = yearMap.get(year + 1);
                        }
                        Object value = StringUtils.EMPTY;
                        if (MapUtils.isNotEmpty(yearData)) {
                            value = yearData.getOrDefault(filed, StringUtils.EMPTY);
                        }
                        rowData[colIndex + year]=value.toString();
                    }
                } else {
                    rowData[colIndex]=convertData(context.getProductType(), filed, map.getOrDefault(filed, StringUtils.EMPTY));
                }
            }
            rowData[0] = String.valueOf(i+1);
            SpireExcelUtil.saveExcelRowData(worksheet, rowData, rowIndex);
            rowIndex++;
        }
    }

    /**
     * 从自定义文档将数据拷贝到导出文档
     * @param workbook
     * @param customResultWorkbook
     * @return
     */
    private org.apache.poi.ss.usermodel.Workbook copySheet(ExportExcelContext context,Workbook workbook, org.apache.poi.ss.usermodel.Workbook customResultWorkbook) {
        try(final ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            workbook.saveToStream(outputStream);
            workbook.dispose();
            final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
            final org.apache.poi.ss.usermodel.Workbook workbookApache = WorkbookFactory.create(inputStream);
            if (!context.isEmptyProject()) {
                final Sheet sheetCreat = workbookApache.createSheet("评价结果");
                final Sheet sheet = customResultWorkbook.getSheetAt(0);
                copyExcelComponent = new CopyExcelComponent();
                // 实际拷贝数据
                //ExcelOperateUtil.copySheet(customResultWorkbook, workbookApache, sheet, sheetCreat);
                copyExcelComponent.copySheet(customResultWorkbook,workbookApache,sheet,sheetCreat,3,-1);
            }
            return workbookApache;
        } catch (Exception e) {
            logger.error("复制sheet页错误 ",e);
            return null;
        }
    }

//    protected abstract String getCostEvaMethod(String targetId);

    protected abstract String getTemplatePath(ProductTypeEnum productTypeEnum);


    /**
     * 导出任务公共参数
     *
     * @param context
     */
    private void exportBatchCommonParam(ExportExcelContext context) {
        // String batchId, Workbook workbook, int sheetIndex, Integer rowIndex;
        final Map<String, String> fieldPositionMap = context.getFieldPositionMap();
        final Workbook workbook = context.getWorkbook();
        Integer rowIndex =getRowIndex(fieldPositionMap,"type");
        final Worksheet worksheet = workbook.getWorksheets().get(context.getSheetIndex());
        final String batchId = context.getId();
        final List<BatchCommonDataVO> batchCommonDataVOS = getBatchCommonDataVOS(batchId);
        if (CollectionUtils.isEmpty(batchCommonDataVOS)) {
            final ImportExcelBatchParamTypeEnum[] values = ImportExcelBatchParamTypeEnum.values();
            for (int i = 0; i < values.length; i++) {
                List<String> rowData = new ArrayList<>();
                rowData.add(values[i].getName());
                rowData.add(StringUtils.EMPTY);
                SpireExcelUtil.saveExcelRowData(worksheet, rowData.toArray(new String[0]), rowIndex+i);
            }
            return;
        }

        final ImportExcelYearDataConfigEnum batchYearParam = ImportExcelYearDataConfigEnum.BATCH_YEAR_PARAM;
        final Map<Integer, BatchCommonDataVO> commonDataVOMap = batchCommonDataVOS.stream().collect(Collectors.toMap(BatchCommonDataVO::getYear, Function.identity(), (v1, v2) -> v1));

        // 根据参数类型写入多行
        for (ImportExcelBatchParamTypeEnum typeEnum : ImportExcelBatchParamTypeEnum.values()) {
            // 每行第一个是参数名称
            // String[] rowData = new String[0];
            List<String> rowData = new ArrayList<>();
            // 参数名称按照年份填充
            rowData.add(typeEnum.getName());

            for (int i = 1; i <= batchYearParam.getYear(); i++) {
                final BatchCommonDataVO batchCommonDataVO = commonDataVOMap.get(i);
                final Map<String, Object> map = JSON.parseObject(JSON.toJSONString(batchCommonDataVO), Map.class);
                if (MapUtils.isEmpty(map)) {
                    rowData.add(StringUtils.EMPTY);
                    continue;
                }
                Object value = map.get(typeEnum.getId());
                if (value == null) {
                    value = StringUtils.EMPTY;
                }
                rowData.add(value.toString());
            }
            // 填充数据
            SpireExcelUtil.saveExcelRowData(worksheet, rowData.toArray(new String[0]), rowIndex);
            // 向下移动一行
            rowIndex++;
        }

    }

    private List<BatchCommonDataVO> getBatchCommonDataVOS(String batchId) {
        final BatchCommonDataDTO batchCommonDataDTO = new BatchCommonDataDTO();
        batchCommonDataDTO.setBatchId(batchId);
        final List<BatchCommonDataVO> batchCommonDataVOS = batchCommonDataService.queryList(batchCommonDataDTO);
        return batchCommonDataVOS;
    }

    private String convertData(ProductTypeEnum productType, String field, Object fieldValue) {
        if (productType == null) {
            throw new ServiceException("产品类别不能为空", "产品类别不能为空", null);
        }
        if (fieldValue == null) {
            return StringUtils.EMPTY;
        }
        switch (field) {
            case "year":
            case "buildYearCount":
            case "evaluationPeriod":
            case "fixedPerson":
                return fieldValue == null ? "" : fieldValue.toString();
            case "productProperty":
                return convertEnumToName(fieldValue, OilProductPropertyEnum.class, OilProductPropertyEnum.class, productType);
            case "areaMark":
                return getEnumName((String) fieldValue, AreaMarkEnum.class);
            case "region":
                return convertEnumToName(fieldValue, OilRegionEnum.class, GasRegionEnum.class, productType);
            case "capacityType":
                return convertEnumToName(fieldValue, OilCapacityTypeEnum.class, GasCapacityTypeEnum.class, productType);
            case "displacementMethod":
                return convertEnumToName(fieldValue, OilDisplacementMethodEnum.class, GasDisplacementMethodEnum.class, productType);
            case "poolType":
                return convertEnumToName(fieldValue, OilPoolTypeEnum.class, GasPoolTypeEnum.class, productType);
            case "evaluationMethod":
                return getEnumName((String) fieldValue, EvaluationMethodEnum.class);
            case "buildOffice":
                return getCompanyName((String) fieldValue);
            case "oilGasField":
                return getOilGasFieldName((String) fieldValue);
            case "name":
                return (String) fieldValue;
            case "other1":
                return getEnumName((String) fieldValue, Other1Enum.class);
            case "other2":
                return getEnumName((String) fieldValue, Other2Enum.class);
            case "passed":
                return getEnumName((String) fieldValue,PassTypeEnum.class);
            case "index":
                return String.valueOf( DataConvertUtil.parse2Int(fieldValue) + 1);
            default:
                return fieldValue == null ? "" : fieldValue.toString();

        }
    }
    //*********************************合并导出******************************************//

    /**
     * 合并导出
     * @param context
     * @return
     */
    public byte[] mergeExportExcel(ExportExcelContext context) {
        final String batchId = context.getId();
       // final BatchInfo batchInfo = batchInfoDAO.selectById(batchId);
        final List<ProjectInfoVO> projectInfoVOS = getProjectInfoVOS(batchId);
        Set<String> computeIdSet = new HashSet<>();
        int maxYear = 0;
        for (ProjectInfoVO projectInfoVO : projectInfoVOS) {
            if (Objects.isNull(projectInfoVO)) {
                continue;
            }
            maxYear = projectInfoVO.getEvaluationPeriod() > maxYear ? projectInfoVO.getEvaluationPeriod():maxYear;
            computeIdSet.add(projectInfoVO.getComputeId());
        }
        // 查询项目计算明细
        final Map<String, List<ProjectYearDataVO>> yearDataVOMap = getProjectYearDataMap(batchId,null);
        final Map<String, List<ProjectReportDetailYearVO>> detailYearMap = getProjectReportDetailListMap(computeIdSet);
        // 生成年列表
        List<Integer> yearList = new ArrayList<>(maxYear);
        for (int i = 0; i < maxYear; i++) {
            yearList.add(i+1);
        }
         List<BatchCommonDataVO> batchCommonDataList = getBatchCommonDataVOS(batchId);
        // 查询模板详情
        final ExportTemplateDetailDTO templateDetailDTO = new ExportTemplateDetailDTO();
        templateDetailDTO.setTemplateId(context.getConfig().getId());
        final List<ExportTemplateDetailVO> templateDetailVOS = exportTemplateDetailService.queryList(templateDetailDTO);
        MergeExportExcelBuilder builder = new MergeExportExcelBuilder(context.getConfig(),context.getExcelExportItemList());
        final org.apache.poi.ss.usermodel.Workbook workbook = builder
                //.batchInfo(context.getComputeInfoDataVO())
                .computeInvokeClient(computeInvokeClient)
                .projectList(projectInfoVOS)
                .batchCommonDataVOMap(batchCommonDataList)
                .exportTemplateDetailList(templateDetailVOS)
                .projectReportDetailYearVOMap(detailYearMap)
                .projectYearDataMap(yearDataVOMap)
                .yearList(yearList)
                // .projectYearDataVOMap(projectYearDataMap)
                .build();
        return convert2Bytes(context,workbook);
    }



    //*********************************批量导出******************************************//
    /**
     * 批量导出
     * @param context
     * @return
     */
    public byte[] batchExportExcel(ExportExcelContext context) {
        // 项目数据
        final String batchId = context.getId();
        final List<ProjectInfoVO> projectInfoVOS = getProjectInfoVOS(batchId);
        Set<String> computeIdSet = new HashSet<>();
        List<Map<String,Object>> projectMapList = new ArrayList<>(projectInfoVOS.size());
        getCompanyList();
        int maxYear = 0;
        for (ProjectInfoVO projectInfoVO : projectInfoVOS) {
            if (Objects.isNull(projectInfoVO)) {
                continue;
            }
            maxYear = projectInfoVO.getEvaluationPeriod() > maxYear ? projectInfoVO.getEvaluationPeriod():maxYear;
            computeIdSet.add(projectInfoVO.getComputeId());
           // final Map<String,Object> map = CglibUtils.beanToMap(projectInfoVO);
            final Map<String, Object> map = BusiUtil.parseObject2Map(projectInfoVO, getExcelExportItemGroupMap(context.getExcelExportItemList()));
            for (String key : map.keySet()) {
                map.put(key,convertProjectData(context.getProductType(),key,map.get(key)));
            }
            map.put("id",projectInfoVO.getId());
            projectMapList.add(map);
        }

        // 查询项目计算明细
        final Map<String, List<ProjectYearDataVO>> yearDataVOMap = getProjectYearDataMap(batchId,null);
        final Map<String, List<ProjectReportDetailYearVO>> detailYearMap = getProjectReportDetailListMap(computeIdSet);
        List<BatchCommonDataVO> batchCommonDataList = getBatchCommonDataVOS(batchId);
        // 查询模板
        //TemplateConfig config = templateService.getTemplateConfig(templateId);
        // 实际计算和生成excel
        final BatchExportExcelBuilder batchExportExcelBuilder = new BatchExportExcelBuilder(context.getConfig(), getExcelExportItemGroupMap(context.getExcelExportItemList()),copyExcelComponent);
        final org.apache.poi.ss.usermodel.Workbook workbook = batchExportExcelBuilder
                .projectMapList(projectMapList)
                .batchCommonDataVOMap(batchCommonDataList)
                .projectReportDetailYearVOMap(detailYearMap)
                .projectYearDataMap(yearDataVOMap)
                .build();
        return convert2Bytes(context,workbook);
    }

    private Map<String, List<ExcelExportItem>> getExcelExportItemGroupMap(List<ExcelExportItem> excelExportItemList) {
        Map<String, List<ExcelExportItem>> excelExportItemGroupMap = new HashMap<>();
        for (ExcelExportItem item : excelExportItemList) {
            List<ExcelExportItem> subList = excelExportItemGroupMap.get(item.getGroup());
            if (subList == null) {
                subList = new ArrayList<>();
                excelExportItemGroupMap.put(item.getGroup(), subList);
            }
            subList.add(item);
        }
        return excelExportItemGroupMap;
    }

    private List<ProjectInfoVO> getProjectInfoVOS(String batchId) {
        final ProjectInfoDTO infoDTO = new ProjectInfoDTO();
        infoDTO.setBatchId(batchId);
        final List<ProjectInfoVO> projectInfoVOS = projectInfoService.queryVOList(infoDTO);
        return projectInfoVOS;
    }

    private Map<String, List<ProjectYearDataVO>> getProjectYearDataMap(String batchId,Set<String> projectIdSet) {
        final ProjectYearDataDTO yearDataDTO = new ProjectYearDataDTO();
        yearDataDTO.setBatchId(batchId);
        yearDataDTO.setProjectIdList(projectIdSet);
        final List<ProjectYearDataVO> projectYearDataVOS = projectYearDataService.queryList(yearDataDTO);
        final Map<String, List<ProjectYearDataVO>> yearDataVOMap = projectYearDataVOS.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(ProjectYearDataVO::getProjectId));
        return yearDataVOMap;
    }
    private Map<String, List<BatchCommonDataVO>> getBatchCommonDataMap(String batchId) {
        final List<BatchCommonDataVO> batchCommonDataVOS = getBatchCommonDataVOS(batchId);
        if (CollectionUtils.isEmpty(batchCommonDataVOS)) {
            return new HashMap<>();
        }
        return batchCommonDataVOS.stream().collect(Collectors.groupingBy(BatchCommonDataVO::getBatchId));
    }

    private Map<String, List<ProjectReportDetailYearVO>> getProjectReportDetailListMap(Set<String> computeIdSet) {
        if (CollectionUtils.isEmpty(computeIdSet)) {
            return new HashMap<>();
        }
        final ProjectReportDetailYearDTO detailYearDTO = new ProjectReportDetailYearDTO();
        detailYearDTO.setFilterComputeIdSet(computeIdSet);
        final List<ProjectReportDetailYearVO> detailYearVOS = projectReportDetailYearService.queryList(detailYearDTO);
        return detailYearVOS.stream()
                .filter(Objects::nonNull).collect(Collectors.groupingBy(ProjectReportDetailYearVO::getProjectId));
    }


    /**
     * 将文档转换为数组
     * @param context
     * @param workbookApache
     * @return
     */
    private byte[] convert2Bytes(ExportExcelContext context, org.apache.poi.ss.usermodel.Workbook workbookApache) {
        byte[] bytes =null;
        if (workbookApache == null) {
            return null;
        }
        try (ByteArrayOutputStream outputStream1  = new ByteArrayOutputStream()){
           // bytes = outputStream1.toByteArray();
            workbookApache.write(outputStream1);
            workbookApache.close();
            bytes = outputStream1.toByteArray();
        } catch (IOException e) {
            logger.error("导出数据失败 targetId:{}", context.getId());
        }
        return bytes;
    }


    private void getCompanyList() {
        COMPANY_LIST.clear();
        final CompanyDTO companyDTO = new CompanyDTO();
        companyDTO.setParentId(officeRootId);
        AjaxResultVO<List<CompanyVO>> companyAjax = officeClient.queryListInner(companyDTO);
        COMPANY_LIST = companyAjax.getData();
    }


    private Object convertProjectData(ProductTypeEnum productType, String field, Object fieldValue) {
        if (productType == null) {
            throw new ServiceException("产品类别不能为空", "产品类别不能为空", null);
        }
        if (fieldValue == null) {
            return StringUtils.EMPTY;
        }
        switch (field) {
            case "product_property":
                return convertEnumToName(fieldValue, OilProductPropertyEnum.class, OilProductPropertyEnum.class, productType);
            case "area_mark":
                return getEnumName((String) fieldValue, AreaMarkEnum.class);
            case "region":
                return convertEnumToName(fieldValue, OilRegionEnum.class, GasRegionEnum.class, productType);
            case "other1":
                return getEnumName((String) fieldValue, Other1Enum.class);
            case "other2":
                return getEnumName((String) fieldValue, Other2Enum.class);
            case "capacity_type":
                return convertEnumToName(fieldValue, OilCapacityTypeEnum.class, GasCapacityTypeEnum.class, productType);
            case "displacement_method":
                return convertEnumToName(fieldValue, OilDisplacementMethodEnum.class, GasDisplacementMethodEnum.class, productType);
            case "pool_type":
                return convertEnumToName(fieldValue, OilPoolTypeEnum.class, GasPoolTypeEnum.class, productType);
            case "evaluation_stage":
                return getEnumName((String) fieldValue, EvaluationMethodEnum.class);
            case "build_office":
                return getCompanyName((String) fieldValue);
            case "oil_gas_field":
                return getOilGasFieldName((String) fieldValue);
            case "name":
                return (String) fieldValue;
            case "passed":
                return getEnumName((String) fieldValue,PassTypeEnum.class);
            case "index":
                return DataConvertUtil.parse2Int(fieldValue) + 1;
            default:
                return fieldValue;

        }
    }

    private String getOilGasFieldName(String fieldValue) {
        if (MapUtils.isNotEmpty(OIL_FILED_MAP)) {
            return OIL_FILED_MAP.getOrDefault(fieldValue,StringUtils.EMPTY);
        }
        final DictValueDTO dto = new DictValueDTO();
        dto.setDictId("oil-field");
        AjaxResultVO<List<DictValueVO>> oilGasFieldAjax = dictValueClient.queryList(dto);
        List<DictValueVO> companyVOList = oilGasFieldAjax.getData();
        if (CollectionUtils.isNotEmpty(companyVOList)) {
            OIL_FILED_MAP = companyVOList.stream().collect(Collectors.toMap(DictValueVO::getCode, DictValueVO::getName, (v1, v2) -> v1));
            return OIL_FILED_MAP.getOrDefault(fieldValue,StringUtils.EMPTY);
        }
        return null;
    }
    private String getCompanyName(String fieldValue) {
        if (MapUtils.isNotEmpty(COMPANY_NAME_MAP)) {
            return COMPANY_NAME_MAP.getOrDefault(fieldValue,StringUtils.EMPTY);
        }

        if (CollectionUtils.isNotEmpty(COMPANY_LIST)) {
            COMPANY_NAME_MAP = COMPANY_LIST.stream().collect(Collectors.toMap(CompanyVO::getId, CompanyVO::getShortName, (v1, v2) -> v1));
            return COMPANY_NAME_MAP.getOrDefault(fieldValue,StringUtils.EMPTY);
        }
        return null;
    }

}
